entry {
    ui::interact-with-window {
        title: { const 'MaybeComponent Demo' },
        content: Root,
        assets: [StyleSheet],
        on-close: { Some { sys::exit 0 } }
    }
};
asset StyleSheet: AssetCSS 'assets/style.css';

type Data enum {
    type Foo { content: String };
    type Bar { a: String, b: String };
    type Baz { ok: Bool };
};
function Foo:
    &(String) => Data
    &(s) => { |Data| { |Foo| { content: s } } };
function Bar:
    &(String,String) => Data
    &(s1,s2) => { |Data| { |Bar| { a: s1, b: s2 } } };
function Baz:
    &(Bool) => Data
    &(p) => { |Data| { |Baz| { ok: p } } };

function LineEdit:
    &(Reactive[String]) => ui::Component
    &(buf) => { { ui::Style ['line-edit'] } { ui::TextView buf } };

function edit:
    &(Reactive[Foo]) => ui::Component
    &(foo) => { LineEdit (foo proj |.(content)|) };
function edit:
    &(Reactive[Bar]) => ui::Component
    &(bar) => { { ui::Box [] } [
        { { ui::Box ['row'] } [{ LineEdit (bar proj |.(a)|) }] },
        { { ui::Box ['row'] } [{ LineEdit (bar proj |.(b)|) }] }
    ] };
function edit:
    &(Reactive[Baz]) => ui::Component
    &(baz) => { { ui::Box ['row','align-center'] } [
        { ui::Checkbox (baz proj |.(ok)|) },
        { ui::Label 'OK' }
    ] };

const Root: ui::Component
    \ use
    let data := { ui::State::[Data] { Foo 'something' } },
    { { ui::Box [] } [
        { { ui::Box ['row'] } [
            { ui::Button ('Foo', (data.in <- { Foo 'foo' })) },
            { ui::Button ('Bar', (data.in <- { Bar ('bar-1','bar-2') })) },
            { ui::Button ('Baz', (data.in <- { Baz Yes })) }
        ] },
        { { ui::Box [] } [
            { ui::MaybeComponent ((data proj? |.(Foo)|), edit) },
            { ui::MaybeComponent ((data proj? |.(Bar)|), edit) },
            { ui::MaybeComponent ((data proj? |.(Baz)|), edit) }
        ] }
    ] };


